﻿using System;
using FunctionalCLR.Core;
using DhbInterfaces;
using DhbFunctionEvaluation;

namespace FunctionalCLR.Shell.Function
{

    /// <summary>
    /// y = derivate(x*x-2*x, x, 10);
    /// echo(x);
    /// echo(y);
    /// </summary>
    public class DerivativeNode : ContextFuncNode
    {
        public DerivativeNode()
            : base("derivate")
        {
        }

        public override object Evaluate()
        {
            if (Parameters.Count < 2)
            {
                throw new ArgumentException(
                    "useage: derivate(expr, param, value)");
            }

            int length = Parameters.Count;

            string param = Convert.ToString(
                Parameters[length - 2].Evaluate());
            Node exprNode = Parameters[length - 1];
            double value = Convert.ToDouble(
                Parameters[length - 3].Evaluate());

            UnaryFunctionTranslator uft
            = new UnaryFunctionTranslator(
                this.Context.GetFunctionManager(), param);
            string fexpr = uft.Translate(exprNode);

            IOneVariableFunctionCompiler compiler =
                new IOneVariableFunctionCompiler();

            IOneVariableFunction func = compiler.Parse(fexpr);
            FunctionDerivative fd = new FunctionDerivative(func);
            double result = fd.Value(value);

            Context.Assign(param, result);

            return result;
        }
    }
}
